package common

import (
	"encoding/json"
	"fmt"
	"time"
)

const (
	//建立连接
	ESTABLISH_CONNECTION = 0
	//心跳
	HEARTBEAT = 1
	//断开连接
	DISCONNECT = -1
	//消息发送
	SEND_MESSAGE = 2
)

// Message 消息
type Message struct {
	//消息类型
	MessageType int `json:"messageType"`
	//消息头
	Header string `json:"header"`
	//消息体
	Body string `json:"body"`
}

// ConnectMessage 连接消息
type ConnectMessage struct {
	//名称
	Name string `json:"name"`
	//客户端名称，为了多端登录使用
	ClientName string `json:"clientName"`
}

// HeartbeatMessage 心跳
type HeartbeatMessage struct {
	//value
	Value string `json:"value"`
	//连接信息
	ConnectMessage ConnectMessage `json:"connectMessage"`
}

type SendMessage struct {
	//连接信息
	ConnectMessage ConnectMessage `json:"connectMessage"`
	//发送人
	Sender string `json:"sender"`
	//接收人
	Receivers []string `json:"receivers"`
	//消息内容
	Body string `json:"body"`
	//消息时间
	Time time.Time `json:"time"`
}

// BuildMessage 构建消息体
func BuildMessage(messageType int, header string, body string) Message {
	message := Message{MessageType: messageType,
		Header: header,
		Body:   body,
	}
	return message
}

// BuildMessageForType 构建消息体
func BuildMessageForType(messageType int, header map[string]string, body interface{}) []byte {
	headerJson, err := json.Marshal(header)
	if err != nil {
		fmt.Errorf("parse param header error :%v", err)
	}
	bodyJson, err := json.Marshal(body)
	if err != nil {
		fmt.Errorf("parse param body error :%v", err)
	}
	message := Message{MessageType: messageType,
		Header: string(headerJson),
		Body:   string(bodyJson),
	}
	messageJson, err := json.Marshal(message)
	if err != nil {
		fmt.Errorf("parse  message error :%v", err)
	}
	return []byte(messageJson)
}

// ParseString 解析消息
func ParseString[T any](string string) T {
	var data T
	err := json.Unmarshal([]byte(string), &data)
	if err != nil {
		fmt.Errorf("parse message error :%v", err)
	}
	return data
}

// ParseBytes 解析消息
func ParseBytes[T any](bytes []byte) T {
	var data T
	err := json.Unmarshal(bytes, &data)
	if err != nil {
		fmt.Errorf("parse message error :%v", err)
	}
	return data
}
